{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(workflow-writing-code)=\n",
    "# Workflow: Writing Code\n",
    "\n",
    "In this chapter, we'll look at the different ways you can both write and run code. This is something that can be very confusing if you're just getting into coding.\n",
    "\n",
    "There are different ways to write (and run) code that suit different needs. For example, for creating a reproducible pipeline of tasks or writing production-grade software, you might opt for a script——a file that is mostly code. But for sending instructions to a colleague or exploring a narrative, you might choose to write your code in a notebook because it can present text and code together more naturally than a script can.\n",
    "\n",
    "We already met some ways to write and run code in the previous chapters. Here, we'll be a bit more systematic so that, by the end of the chapter, you'll be comfortable writing code in both scripts and notebooks. For advanced users, there's also information on how to write code with markdown, using markdown files that contain executable code chunks. Scripts and notebooks are by far the most popular ways to write code though.\n",
    "\n",
    "Let's start with some definitions.\n",
    "\n",
    "- IDE, or **integrated development environment**: this is the application that you write code of all different kinds in (scripts, notebooks, markdown). This book recommends Visual Studio Code as an IDE. It supports many languages. Making an analogy with writing documents, VS Code is to programming languages what a word processor is for actual written languages. JupyterLab is another IDE, but one which is geared towards the use of notebooks.\n",
    "- the **interpreter**: this is the programming language (eg Python) that has to be installed separately onto your computer. Its what takes your written commands and turns them into actions. VS Code and other IDEs will use whatever interpreters they can find on your computer and use them to execute the code you've written.\n",
    "- **scripts**: these are files that almost exclusively contain code. They can be edited and run in an IDE. Python scripts always have the file extension `.py`.\n",
    "- **notebooks**: aka Jupyter Notebooks, these are files that can contain code and text in different blocks called \"cells\". They can be edited, and the code parts can be run, in an IDE. Jupyter Notebooks always have the file extension `.ipynb`. Notebooks can be export to other formats, like word documents, HTML pages, PDFs, and even slides!\n",
    "- **the terminal**: this is the text interface that you use to send instructions to your computer's operating system. It's typically what you use to install new packages, for example with commands like `pip install packagename`. Although your computer will come with a separate terminal application too, you can open a terminal in VS Code by clicking on Terminal > New Terminal at the top of your VS Code window.\n",
    "- **markdown**: this is a lightweight language that turns simple text commands into professional looking documents. It's widely used by people who code. It's also what's used for the text cells in Jupyter Notebooks. When not in a notebook, files containing markdown always have the extension `.md`. With the Visual Studio Code markdown extensions installed, you can right-click within a Markdown file in VS Code and then select *Markdown Preview Enhanced* to see how the rendered document will look. The difference between HTML code and the same website viewed in a browser like Chrome is a good analogy for the difference between what you see in a `.md` file and what you see in the preview of that markdown file.\n",
    "- **quarto markdown**: this is a special variant of markdown, with file extension `.qmd`, that can be used to combine text and code that gets executed so that code outputs are inserted into final outputs such as html or pdf documents.\n",
    "\n",
    "Let's now turn to all of the different ways you can write code in a fully-featured integrated development environment like Visual Studio Code. They each have pros and cons, and you're likely to want to use them at different times. The table below sets out all of the different ways you can write, and execute, code.\n",
    "\n",
    "If you're looking for a typical workflow, this book recommends working with scripts (files that end in `.py`) and the VS Code interactive window. Remember, if you're working with a `.py` file, you can always open the Visual Studio Code interactive window by right-clicking somewhere within the script and selecting 'Run in interactive window'.\n",
    "\n",
    "\n",
    "| What | How to use  | Prerequisites | Pros | Cons\n",
    "|------|----------------|---------------|---------------|---------------|\n",
    "| Script, eg `script.py`   |   'Run in interactive window' in an integrated development environment (IDE)         | Python installation + an IDE with Python support, eg Visual Studio Code. | Can be run all-in-one or step-by-step as needed. Very powerful tools available to aid coding in scripts. De facto standard for production-quality code. Can be imported by other scripts. Version control friendly. | Not very good if you want to have lots of text alongside code.\n",
    "| Jupyter Notebook, eg `notebook.ipynb`   | Open the file with Visual Studio Code.     |   Use Visual Studio Code and the VS Code Jupyter extension. | Code and text can alternate in the same document. Rich outputs of code can be integrated into document. Can export to PDF, HTML, and more, with control over whether code inputs/outputs are shown, and either exported directly or via **Quarto**. Can be run all-in-one or step-by-step as needed. | Fussy to use with version control. Code and text cannot be mixed in same 'cell'. Not easy to import in other code files.\n",
    "| Markdown with executable code chunks using [**Quarto**](https://quarto.org/), eg `markdown_script.qmd` | To produce output, write in a mix of markdown and code blocks and then export with commands like `quarto render markdown_script.qmd --to html` on the command line or using the [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=quarto.quarto). Other output types available. | Installations of Python and Quarto, plus their dependencies. | Allows for true mixing of text and code. Can export to wide variety of other formats, such as PDF and HTML, with control over whether code inputs/outputs are shown. Version control friendly. | Cannot be imported by other code files.\n",
    "\n",
    "Some of the options above make use of the command line, a way to issue text-based instructions to your computer. Remember, the command line (aka the terminal) can be accessed via the Terminal app on Mac, the Command Prompt app on Windows, or <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>t</kbd> on Linux. To open up the command line within Visual Studio Code, you can use the keyboard shortcut <kbd>⌃</kbd> + <kbd>\\`</kbd> (on Mac) or \n",
    "<kbd>ctrl</kbd> + <kbd>\\`</kbd> (Windows/Linux), or click \"View > Terminal\".\n",
    "\n",
    "Now let's look at each of these ways to run code in more detail using a common example: Hello World!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Scripts\n",
    "\n",
    "Most code is written in scripts and they should be your go to.\n",
    "\n",
    "We already met scripts, but let's have a recap. Create a new file in Visual Studio Code called `hello_world.py`. In the Visual Studio Code editor, add a single line to the file:\n",
    "\n",
    "```python\n",
    "print('Hello World!')\n",
    "```\n",
    "\n",
    "Save the file. Right-click and, to run the script, you can either use 'Run current file in interactive window', or 'Run current file in terminal', or 'Run selection/line in interactive window'. These are two different methods of running the script: in the IDE (VS Code in this case) or in the command line.\n",
    "\n",
    "A typical workflow would be selecting some lines within a script, and then hitting 'Run selection/line in interactive window' or using the keyboard shortcut of <kbd>shift</kbd> + <kbd>enter</kbd>.\n",
    "\n",
    "As an alternative for the latter, you can open up the command line yourself and run\n",
    "\n",
    "```bash\n",
    "python hello_world.py\n",
    "```\n",
    "\n",
    "which will execute the script."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Jupyter Notebooks\n",
    "\n",
    "Jupyter Notebooks are for experimentation, tinkering, and keeping text and code together. They are the lab books of the coding world. This book is mostly written in Jupyter Notebooks! The name, 'Jupyter', is a reference to the three original languages supported by Jupyter, which are Julia, Python, and R, and to Galileo's notebooks recording the discovery of the moons of Jupiter. Jupyter notebooks now support a vast number of languages beyond the original three, including Ruby, Haskell, Go, Scala, Octave, Java, and [more](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels).\n",
    "\n",
    "To get started with Jupyter Notebooks, you'll need to have a Python installation and to run `pip install jupyterlab` on the command line.\n",
    "\n",
    "If you get stuck with this tutorial, there's a more in-depth VS Code and Jupyter tutorial available [here](https://code.visualstudio.com/docs/python/jupyter-support).\n",
    "\n",
    "Create a new file in Visual Studio Code and save it as `hello_world.ipynb`. Close the file and re-open it. The notebook interface should automatically load and you'll see options to create cells with plus signs labelled 'Code' and 'Markdown'. A cell is an independent chunk of either code or text. Text cells have markdown in them, a lightweight language for creating text outputs that you will find out more about in {ref}`markdown`. For now, create a markdown cell containing the following:\n",
    "\n",
    "```markdown\n",
    "# This is a title\n",
    "\n",
    "## This is a subtitle\n",
    "\n",
    "This notebook demonstrates printing 'hello world!' to screen.\n",
    "```\n",
    "\n",
    "Now, for the next cell, choose code and write:\n",
    "\n",
    "```python\n",
    "print('hello world!')\n",
    "```\n",
    "\n",
    "To run the notebook, you can choose to run all cells (usually a double play button at the top of the notebook page) or just each cell at a time (a play button beside a cell). 'Running' a markdown cell will render the markdown in display mode; running a code cell will execute it and insert the output below. When you play the code cell, you should see the 'hello world!' message appear.\n",
    "\n",
    "Jupyter Notebooks are versatile and popular for early exploration of ideas, especially in fields like data science. This entire book is written in a combination of Jupyter Notebooks and executable markdown (more on that in a moment). Jupyter Notebooks can easily be run in the cloud using a browser too (via Binder or Google Colab) without any prior installation. Although it's not got very much code in, the page you're reading now can be loaded into Google Colab as a Jupyter Notebook by clicking 'Colab' under the rocket icon at the top of the page.\n",
    "\n",
    "One really nice feature of Jupyter Notebooks is that you can use them as the input files for **Quarto** instead of using `.qmd` files, and this opens up many export options and possibilities (like hiding some code inputs). You can find more information [here](https://quarto.org/docs/computations/python.html) (look for the guidance on Jupyter Notebooks aka `.ipynb` files) or look ahead to the chapters on {ref}`markdown` and {ref}`quarto`.\n",
    "\n",
    "You can try a Jupyter Notebook without installing anything online at [https://jupyter.org/try](https://jupyter.org/try). Click on Try Classic Notebook for a tutorial.\n",
    "\n",
    "### Tips when using Jupyter Notebooks\n",
    "\n",
    "- Version control: if you are using version control, be wary of saving the outputs of Jupyter Notebooks when you only want to save code. Most IDEs that support Jupyter Notebooks have a clear outputs option. You can also automate this as a *pre-commit git hook* (if you don't know what that is, don't worry). You could also pair your notebook to a script or markdown file (covered in the next section). Outputs or not, Jupyter Notebooks will render on github.\n",
    "\n",
    "- Terminal commands: these can be run from inside a Jupyter Notebook by placing a `!` in front of the command and executing the cell. For example, `!ls` gives the directory the notebook is in. You can also `!pip install` and `!conda install` in this way. This works in Google Colab notebooks too.\n",
    "\n",
    "- Magic commands: statements that begin with `%` are magic commands. `%whos` displays information about defined variables. `%run script.py` runs a script called `script.py`. `%timeit` times how long the cell takes to execute. Finally, you can see many more magic commands using  `%quickref`.\n",
    "\n",
    "- Notebook cells can be executed in any sequence you choose. But if you're planning to share your notebook or use it again for yourself, it's good practice to check that its cells do what you want *when run in sequence*, from top to bottom.\n",
    "\n",
    "- There are tons of extensions to Jupyter Notebooks; you can find a list [here](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions.html). Of particular note is [ipywidgets](https://ipywidgets.readthedocs.io/en/stable/index.html), which adds interactivity.\n",
    "\n",
    "- Get help info on a command by running it but with `?` appended to end."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Markdown with Executable Code Chunks\n",
    "\n",
    "This is by far the least common way of coding, though it has gained popularity in recent years and it's great if you're going to ultimately export to other formats like slides, documents, or even a website!\n",
    "\n",
    "When you have much more text combined code, even using Jupyter Notebooks can feel a bit onerous and, historically, editing the text in a notebook was a bit tedious - especially if you wanted to move cells around a lot. Markdown makes for a much more pleasant writing experience. But markdown on its own cannot execute code—but imagine you want to combine reproducibility, text, and code + code outputs: however, there is a tool called **Quarto** that allows you to do this by adding executable code chunks to markdown.\n",
    "\n",
    "As this is a bit more of an advanced topic, and as much about communication as it is about writing code, we'll come back to how to do it in {ref}`quarto`.\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "c4570b151692b3082981c89d172815ada9960dee4eb0bedb37dc10c95601d3bd"
  },
  "kernelspec": {
   "display_name": "Python 3.8.12 64-bit ('codeforecon': conda)",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
